// LocalListview.cpp : implementation file
//

#include "stdafx.h"
#include "MyFtp.h"
#include "MainFrm.h"
#include "LocalListview.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLocalListview

IMPLEMENT_DYNCREATE(CLocalListview, CListView)

CLocalListview::CLocalListview()
{
}

CLocalListview::~CLocalListview()
{
}


BEGIN_MESSAGE_MAP(CLocalListview, CListView)
	//{{AFX_MSG_MAP(CLocalListview)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLocalListview drawing

void CLocalListview::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CLocalListview diagnostics

#ifdef _DEBUG
void CLocalListview::AssertValid() const
{
	CListView::AssertValid();
}

void CLocalListview::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLocalListview message handlers

void CLocalListview::OnInitialUpdate() 
{
	CListView::OnInitialUpdate();

	//Set imagelist
	CMainFrame* pFrame=(CMainFrame*)GetParentFrame();
	GetListCtrl().SetImageList(&pFrame->m_imageSmall,LVSIL_SMALL);

	//Set style
	this->ModifyStyle(0, WS_VISIBLE|WS_CHILD|WS_BORDER|LVS_REPORT|LVS_EX_FULLROWSELECT, 0);

	//Set columns
	CString columns[] = {_T("Name"), _T("Size"), _T("Type"), _T("Date Modified")};
	CListCtrl &ctrl = GetListCtrl();
	int i;
	for(i = 0; i < 4; i++)
	{
		ctrl.InsertColumn(i, columns[i]);
	}
	
	ctrl.SetColumnWidth(0, 150);
	ctrl.SetColumnWidth(1, 100);
	ctrl.SetColumnWidth(2, 100);
	ctrl.SetColumnWidth(3, 100);

	m_csCurDir = _T("C:\\");
	ListDir(m_csCurDir);
}

void CLocalListview::ListDir(CString csDir)
{
	CFileFind *pFinder = new CFileFind();

	CString csWildcard(csDir);
	csWildcard += _T("\\*.*");
	BOOL bWorking = pFinder->FindFile(csWildcard);
	CListCtrl &theCtrl = GetListCtrl();
	SHFILEINFO fileinfo;
	CTime tempTime;
	CString csTemp;

	theCtrl.DeleteAllItems();

	while(bWorking)
	{
		bWorking = pFinder->FindNextFile();

		if(pFinder->IsDots())
		{
			csTemp = pFinder->GetFileName();

			if(csTemp.Compare(_T(".")) == 0)
			{
				continue;	//skip '.'
			}

			GetFileInfo(pFinder->GetFilePath(), fileinfo);
			int item = theCtrl.InsertItem(0, csTemp, fileinfo.iIcon);
		}
		else if(pFinder->IsDirectory())
		{
			GetFileInfo(pFinder->GetFilePath(), fileinfo);

			int item = theCtrl.InsertItem(0, 
				pFinder->GetFileName(), fileinfo.iIcon);

			if(item != -1)
			{
				//file type
				theCtrl.SetItemText(item, 2, fileinfo.szTypeName);

				//Last modified
				if(pFinder->GetLastWriteTime(tempTime))
				{
					csTemp = tempTime.Format(_T("%c"));
				}
			    else
				{
					csTemp = _T("unavailable");
				}

				theCtrl.SetItemText(item, 3, csTemp);
			}

		}
		else
		{
			GetFileInfo(pFinder->GetFilePath(), fileinfo);

			int item = theCtrl.InsertItem(0, 
				pFinder->GetFileName(), fileinfo.iIcon);

			if(item != -1)
			{
				//file size
				CString csSize;
				csSize.Format(_T("%I64u"), pFinder->GetLength());
				theCtrl.SetItemText(item, 1, csSize);

				//file type
				theCtrl.SetItemText(item, 2, fileinfo.szTypeName);

				//Last modified
				if(pFinder->GetLastWriteTime(tempTime))
				{
					csTemp = tempTime.Format(_T("%c"));
				}
			    else
				{
					csTemp = _T("unavailable");
				}

				theCtrl.SetItemText(item, 3, csTemp);
			}
		}
	}

	pFinder->Close();
	delete pFinder;

	theCtrl.UpdateData(FALSE);
}

void CLocalListview::GetFileInfo(CString &fileName, SHFILEINFO& shFi)
{
	CString str=fileName; 

	if(!SHGetFileInfo(str,0,&shFi,sizeof(shFi),SHGFI_ICON|SHGFI_SMALLICON|SHGFI_DISPLAYNAME|SHGFI_TYPENAME)) 
	{ 
		return; 
	}

	DestroyIcon(shFi.hIcon); 
}

void CLocalListview::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CListCtrl& theCtrl = GetListCtrl();
	int i = theCtrl.GetSelectionMark();
	CString csName = theCtrl.GetItemText(i, 0);

	if(csName == _T(""))
	{
		ASSERT(0);
	}
	else
	{
		CString csType = theCtrl.GetItemText(i, 2);

		if(csType.CompareNoCase(_T("Folder")) == 0)
		{
				EnterFolder(theCtrl.GetItemText(i, 0));
		}
		else if(csType == _T(""))
		{
			if(csName == _T(".."))
			{
				UpOneFolder();
			}
		}
		else
		{
			//Must be file
			Execute(csName);
		}
	}
	
	*pResult = 0;
}


void CLocalListview::EnterFolder(CString csName)
{
	m_csCurDir.TrimRight(_T('\\'));
	m_csCurDir = m_csCurDir + _T("\\") + csName;
	ListDir(m_csCurDir);
}

void CLocalListview::UpOneFolder()
{
	CString csTemp = m_csCurDir;
	csTemp.TrimRight(_T('\\'));

	int index = csTemp.ReverseFind(_T('\\'));

	if(index > 0)
	{
		m_csCurDir = csTemp.Left(index);
	}
	ListDir(m_csCurDir);
}

void CLocalListview::Execute(CString csName)
{
	CString csTemp = m_csCurDir;
	csTemp.TrimRight(_T('\\'));

	ShellExecute(NULL, _T("open"), csTemp + _T("\\") + csName, 
		NULL, NULL, SW_SHOWNORMAL);
}
